/**
 *微信支付获取订单详情和支付签名
 */
var _ = require("underscore"),
	crypto = require("crypto");
var debug = require("debug")("consultant:utils");
var models = require("../models"),
	Token = models.Token,
	MUser = models.MUser;
var wc = require('wechat');
var settings = require('../config');
var OAuth = require('wechat').OAuth;
var wechat = function() {

};
/**
 *md5加密
 */
wechat.prototype.md5 = function(content) {
	debug("before md5:" + content);
	var crypto_md5 = crypto.createHash('md5');
	crypto_md5.update(new Buffer(content, "UTF8"), "UTF8 ");
	var content_md5 = crypto_md5.digest('hex');
	debug("after md5: " + content_md5);
	return content_md5;
}
/**
 *sha1加密
 */
wechat.prototype.sha1 = function(content) {
	debug("before sha1:" + content);
	var crypto_sha1 = crypto.createHash('sha1');
	crypto_sha1.update(new Buffer(content, "UTF8"), "UTF8");
	var content_sha1 = crypto_sha1.digest('hex');
	debug("after sha1: " + content_sha1);
	return content_sha1;
}
/**
 *ASCII数组排序
 */
wechat.prototype.sort = function(obj) {
	debug("old json: ", obj);
	// get array
	var params = [];
	_.each(obj, function(value, key, list) {
		params.push(key);
	});
	//sort 
	debug("sort before: " + params);
	params.sort();
	debug("sort after: " + params);
	//new json
	var newobj = {};
	_.each(params, function(value, index, list) {
		newobj[value] = obj[value];
	});
	debug("new json: ", newobj);
	return newobj;
}
/**
 *json对象转换为url字符串
 */
wechat.prototype.json2string = function(obj) {
	var obj_str = "";
	_.each(obj, function(value, key, list) {
		if (obj_str) {
			obj_str += "&" + key + "=" + value;
		} else {
			obj_str += key + "=" + value;
		}
	});
	return obj_str;
}
/**
 * json对象转xml字符串
 */
wechat.prototype.json2xml = function(json, root){
	var str = '<?xml version="1.0" encoding="UTF-8" >';
	str += '<' + root + '>';
	_.each(json, function(value, key, list){
		str += '<' + key + '>' + value + '</' + key + '>';
	});
	str += '</' + root + '>';
	return str;
}

wechat.prototype.urlencode = function(newpkg) {
	var newpkg_encode = {};
	_.each(newpkg, function(value, key, list) {
		newpkg_encode[key] = encodeURIComponent(value);
	});
	return newpkg_encode;
}

/**
 *提供wechat api并且保证api的accesstoken能有效使用
 */
wechat.prototype.getAPI = function(callback, refresh) {
	var tokenDao = new Token();
	var _api = new wc.API(settings.wc_appid, settings.wc_appsecret);
	if (refresh) { //如果调用者发现获得的accesstoken已经无效，可以传过来refresh=true参数对accesstoken进行刷新。
		getAccessToken(_api, function(api) {
			updateToken("token123", api, tokenDao, callback);
		});
	} else {
		tokenDao.findTokenById("token123", function(err, token) {
			if (err) {
				debug("find token fail", err);
				return err;
			}
			if (token) {
				//从数据库中获得
				var apitoken = new wc.API.AccessToken(); //wechat需要对token进行isValid验证
				apitoken.accessToken = token.token;
				apitoken.expireTime = token.expireTime;
				_api.token = apitoken;
				if (!_api.token.isValid()) { //如果token 超时
					getAccessToken(_api, function(api) {
						updateToken("token123", api, tokenDao, callback);
					});
				} else {
					callback(_api);
				}
			} else {
				getAccessToken(_api, function(api) {
					tokenDao.id = "token123";
					tokenDao.token = api.token.accessToken;
					tokenDao.expireTime = api.token.expireTime;
					tokenDao.date = new Date();
					tokenDao.saveToken(tokenDao, function(err) {
						debug("add new token in db", err);
						callback(api);
					});
				});
			}
		});
	}
};
/**
 *获取微信网页授权凭证access_token
 */
wechat.prototype.getOAuth = function(code, callback) {
	var oauth = new OAuth(settings.wc_appid, settings.wc_appsecret);
	var tokenDao = new Token();
	tokenDao.findTokenById("oauth123", function(err, token) {
		if (err) {
			debug("findTokenById fail", err);
		} else if (token) {
			oauth.accessToken = token.token;
			oauth.refreshToken = token.refreshToken;
			oauth.expireTime = token.expireTime;
			if (!oauth.isAccessTokenValid()) { //token无效时执行
				oauth.refreshAccessToken(function(err, result) {
					if (err) {
						//删除更新access_token
						tokenDao.removeTokenById("oauth123", function(err) {
							getOAuthAccessToken(oauth, code, callback);
						})
					} else {
						//更新access_token
						updateToken("oauth123", oauth, tokenDao, function(err) {
							debug("update token", err);
							callback(oauth, result);
						});
					}
				})
			} else {
				getOAuthAccessToken(oauth, code, callback);
			}
		} else {
			getOAuthAccessToken(oauth, code, callback);
		}
	})
}

/**
 *从微信平台过去access_token
 */
function getAccessToken(api, callback) {
	api.getAccessToken(function(err, result) {
		if (err) {
			debug("getAccessToken fail", err);
			return err;
		}
		if (result) {
			// return api
			callback(api);
		}
	});
}
/**
 *更新数据库Token
 *api从平台中获取的含access_token的api
 *tokenDao TokenModel
 */
function updateToken(tokenid, api, tokenDao, callback) {
	var options;
	if (tokenid == "oauth123") {
		options = {
			token: api.accessToken,
			expireTime: api.expireTime,
			refreshToken: api.refreshToken
		}
	} else {
		options = {
			token: api.token.accessToken,
			expireTime: api.token.expireTime
		}
	}
	tokenDao.updateTokenById(tokenid, options, function(err) {
		debug("add new token in db", err);
		callback(api);
	});
}


function getOAuthAccessToken(oauth, code, callback) {
	oauth.getAccessToken(code, function(err, result) {
		debug("getAccessToken", result);
		var tokenDao = new Token();
		tokenDao.findTokenById("oauth123", function(err, token) {
			if (token) {
				//删除access_token
				new Token().removeTokenById("oauth123", function(err) {
					//存储access_token
					var tokenDao = new Token();
					tokenDao.id = "oauth123";
					tokenDao.token = oauth.accessToken;
					tokenDao.refreshToken = oauth.refreshToken;
					tokenDao.expireTime = oauth.expireTime;
					tokenDao.date = new Date();
					tokenDao.saveToken(tokenDao, function(err) {
						debug("add new token in db", err);
						callback(oauth, result);
					});
				})
			} else {
				//存储access_token
				var tokenDao = new Token();
				tokenDao.id = "oauth123";
				tokenDao.token = oauth.accessToken;
				tokenDao.refreshToken = oauth.refreshToken;
				tokenDao.expireTime = oauth.expireTime;
				tokenDao.date = new Date();
				tokenDao.saveToken(tokenDao, function(err) {
					debug("add new token in db", err);
					callback(oauth, result);
				});
			}
		})
	})
}

wechat.getOauthOpenid = function(appid, code, callback){

	//# 通过appid获取公众号信息
	new MUser().findMUser({appID:appid}, function(err, muser){

		//# 使用公众号appid和appsecrect和code获取openid或accesstoken
		var oauth = new OAuth(appid, muser.appSecret);
		oauth.getAccessToken(code, function (err, result) {
			callback(err, result);
		});
	})
}

module.exports = wechat;